'''
= Code Profiling =

Easy API to print profiling reports. Call profile with a function as its
argument and a profile of the function will be printed to stdout.
'''

from cProfile import Profile, label


def name(function):
    '''Global name of a function, including file and line.'''
    
    path, line, name = label(function)
    file = path.split('/')[-1]
    
    return '%-15s %4d %s' % (file, line, name)


def string(call, indent = 0):
    '''String format of a function call.'''
    function, cc, nc, tt, ct = call[:5]
    
    return '%8.3f %8.3f %8d %8d %s%s' % (tt, ct, cc, nc,
                                         ' ' * indent, name(function))


def profile(function):
    '''Prints the profile of a function to stdout.'''
    
    print('=== Profiling %s ===' % function.__name__)
    
    profiler = Profile()
    profiler.runctx('function()', {'function': function}, {})
    
    stats = profiler.getstats()
    stats.sort(lambda a, b: -cmp(a[3], b[3]))
    
    for call in stats[:30]:
        print(string(call))
        
        if call[-1] is not None:
            call[-1].sort(lambda a, b: -cmp(a[3], b[3]))
            
            for subcall in call[-1][:10]:
                print(string(subcall, 4))
